
import Food from "./food"
import ScorePanel from "./scorePanel";
import Snake from "./snake";

// 游戏控制器
class GameControl {
  snake: Snake
  food: Food
  scorePanel: ScorePanel

  // 蛇运动方向
  direction: string = "ArrowRight"

  // 游戏是否结束变量
  isLive = true

  constructor() {
    this.snake = new Snake()
    this.scorePanel = new ScorePanel()
    this.food = new Food()

    this.init()
  }

  // 游戏初始化
  init() {
    // this.keydownHandler 如果这样直接调用,函数内部的this指向的是事件绑定的对象即: #document
    // this.keydownHandler.bind 创建了一个新的函数再把当前对象传入
    document.addEventListener('keydown', this.keydownHandler.bind(this))
    this.run()
  }

  // 键盘按下事件
  /* 
    ArrowUp
    ArrowRight
    ArrowDown
    ArrowLeft 
  */
  keydownHandler(evenr: KeyboardEvent) {
    // console.log(this)
    // console.log('evenr', evenr.code)
    if((evenr.code === 'ArrowUp' && this.direction != 'ArrowDown') || (evenr.code === 'ArrowRight' && this.direction != 'ArrowLeft') || (evenr.code === 'ArrowDown' && this.direction != 'ArrowUp') || (evenr.code === 'ArrowLeft' && this.direction != 'ArrowRight')) {
      this.direction = evenr.code
    }
  }

  // 蛇移动的方法
  run() {
    // 获取蛇坐标
    let X = this.snake.X
    let Y = this.snake.Y

    switch (this.direction) {
      case 'ArrowUp':
        Y -= 10
        break;
      case 'ArrowDown':
        Y += 10
        break;
      case 'ArrowLeft':
        X -= 10
        break;
      case 'ArrowRight':
        X += 10
        break;
    }

    // 检查蛇是否吃到食物 改变食物位置
    this.checkEat(X, Y)

    try {
      this.snake.X = X
      this.snake.Y = Y
    } catch (error: any) {
      alert(error.message + ' 游戏结束')
      this.isLive = false
    }

    this.isLive && setTimeout(this.run.bind(this), 300 - (this.scorePanel.level - 1) * 30)
  }

  // 定义蛇吃到食物
  checkEat(X: number, Y: number) {
    if(X === this.food.X && Y === this.food.Y) {
      this.food.change()
      this.scorePanel.addScore()
      this.snake.addBody()
    }
  }

}

export default GameControl